首页 > 试题广场 >

螺旋矩阵

[编程题]螺旋矩阵
  • 热度指数:139185 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个m x n大小的矩阵(m行,n列),按螺旋的顺序返回矩阵中的所有元素。

数据范围:,矩阵中任意元素都满足
要求:空间复杂度 ,时间复杂度
示例1

输入

[[1,2,3],[4,5,6],[7,8,9]]

输出

[1,2,3,6,9,8,7,4,5]
示例2

输入

[]

输出

[]
这里首先要理解一下左边界(left)、右边界(right)、上边界(up)、下边界(down)的意义:
以例题为例:
左边界是表示:二维列表里面的每一个小列表的左边界  [1,2,3] 中的1就是做左边界
右边界是表示:二维列表里面的每一个小列表的右边界  [1,2,3] 中的3就是做右边界
上边界是表示:二维列表里面的每一个小列表的在大列表的上边界  [1,2,3] 就是做上边界
下边界是表示:二维列表里面的每一个小列表的在大列表的下边界  [7,8,9] 就是做下边界
然后再进行螺旋的遍历:
1.在上边界中 ,从左到右遍历
2.在右边界中 ,从上到下遍历
3.在下边界中 ,从右到左遍历
4.在左边界中,从下上上遍历
这4中顺序弄完后,接下来就是重复这四个过程,那只要加上边界移动跳出判断就可以了
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param matrix int整型二维数组 
# @return int整型一维数组
#
class Solution:
    def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
        if not matrix:
            return []
        result = []
        left = 0
        right = len(matrix[0]) - 1
        up = 0
        down = len(matrix) - 1
        while left <= right and up <= down:
            # 在上边界,从左到右
            for i in range(left,right+1):
                result.append(matrix[up][i])
            # 上边界向下
            up += 1
            if up > down:
                break
            # 在右边界,从上到下
            for i in range(up,down+1):
                result.append(matrix[i][right])
            # 右边界向左
            right -= 1
            if left > right:
                break
            # 在下边界,从右到左
            for i in range(right,left-1,-1):
                result.append(matrix[down][i])
            # 下边界向上
            down -= 1
            if up > down:
                break
            # 在左边界,从下到上
            for i in range(down,up-1,-1):
                result.append(matrix[i][left])
            # 左边界右移
            left += 1
            if left > right:
                break
        return result



编辑于 2024-01-10 17:57:26 回复(0)
class Solution:
    def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
        # 接收并处理数据
        res=[]
        # 讨论是否为空
        if matrix==[]:
            return res
        else:
            while 1 :
                new=[]
                # 取第一行为结果的一部分并删除第一行
                for t in matrix[0]:
                    res.append(t)
                del matrix[0]
                # 判断是否结束
                if matrix ==[]:
                    break
                # 旋转矩阵
                for t in range(len(matrix[0])):
                    data=[]
                    for t1 in matrix:
                        data.append(t1[len(matrix[0])-1-t])
                    new.append(data)
                matrix=new

            return res
还行吧,过程挺巧的
发表于 2022-08-17 22:02:26 回复(0)
class Solution:
    def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
        # write code here
        if not matrix:
            return []
        res = []
        while matrix:
            res.extend(matrix.pop(0))
            matrix = list(zip(*matrix))[::-1]
        return res

发表于 2022-07-03 16:33:03 回复(0)

遍历矩阵中的每一个元素
时间复杂度:O(mn) 空间复杂度:O(1)

class Solution:
    def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
        res = []
        n = len(matrix)
        if n == 0:
            return res
        left = 0
        right = len(matrix[0]) - 1
        up = 0
        down = n - 1
        while left <= right and up <= down:
            for i in range(left, right+1):
                res.append(matrix[up][i])
            up += 1
            if up > down:
                break

            for i in range(up, down+1):
                res.append(matrix[i][right])
            right -= 1
            if right < left:
                break

            i = right
            while i >= left:
                res.append(matrix[down][i])
                i -= 1
            down -= 1
            if down < up:
                break

            i = down
            while i >= up:
                res.append(matrix[i][left])
                i -= 1
            left += 1
            if left > right:
                break
        return res

挨打解法

class Solution:
    def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
        res = []
        while matrix:
            res += matrix[0]
            matrix = list(zip(*matrix[1:]))[::-1]
        return res
发表于 2022-05-28 19:07:24 回复(0)
class Solution:
    def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
        # write code here
        ans = []
        while matrix:
            ans.extend(matrix.pop(0))
            matrix = list(zip(*matrix))[::-1]
        return ans

发表于 2022-03-07 11:05:59 回复(0)
这题写得有点费劲

class Solution:
    def spiralOrder(self , matrix: List[List[int]]) -> List[int]:
        # 拓宽visit矩阵的纬度,使得已访问检测和矩阵超界检测统一
        
        seq = []
        if len(matrix) == 0:
            return matrix
        if len(matrix) == 1:
            return matrix[0]
        visit = [[0 for _ in range(len(matrix[0])+2)] for _ in range(len(matrix)+2)]
        for i in range(len(visit[0])):  # 遍历列
            visit[0][i] = 1
            visit[len(visit)-1][i] = 1
        for i in range(len(visit)):     # 遍历行
            visit[i][0] = 1
            visit[i][len(visit[0])-1] = 1
            
        
        
        curDir = 'right'
        i = j = 1
        changeTimes = 0
        while True:
            if changeTimes == 2:
                break
            if not visit[i][j]:      # dir unchange
                visit[i][j] = 1
                seq.append(matrix[i-1][j-1])
                i, j = self.nextInd(i, j, curDir)
                changeTimes = 0
            else:                    # dir change
                # 退回上一步, 改变方向
                i, j = self.preInd(i, j, curDir)
                curDir = self.changeDir(curDir)
                i, j = self.nextInd(i, j, curDir)
                changeTimes += 1
        return seq
    
    
    def nextInd(self, i, j, curDir):
        if curDir == 'down':
            i += 1
        elif curDir == 'up':
            i -=1
        elif curDir == 'right':
            j += 1
        elif curDir == 'left':
            j -= 1
        return i, j
    
    def preInd(self, i, j, curDir):
        if curDir == 'down':
            i -= 1
        elif curDir == 'up':
            i +=1
        elif curDir == 'right':
            j -= 1
        elif curDir == 'left':
            j += 1
        return i, j
                
        
    def changeDir(self, curDir):
        if curDir == 'right':
            return 'down'
        elif curDir == 'down':
            return 'left'
        elif curDir == 'left':
            return 'up'
        elif curDir == 'up':
            return 'right'
        


发表于 2022-03-03 16:36:51 回复(0)
class Solution:
    def spiralOrder(self , matrix):
        
        
        
        #行
        m = len(matrix)
        if( m == 0 ):
            return []
        #列
        n = len(matrix[0])
        if (n == 0):
            return []
        
        mapbook = [[1 for i in range(n)] for j in range(m)]


        #print(mapbook)
        #print("m:",m)
        #print("n:",n)

        r = 0
        c = -1
        res = []
        for i in range(m*n):
            #右
            while( c < n-1 and mapbook[r][c+1]==1 ):
                c = c + 1
                res.append(matrix[r][c])
                mapbook[r][c] = 0
                #print("右")
                #print(mapbook)
            #下
            while( r < m -1 and mapbook[r+1][c] == 1  ):
                r = r + 1
                res.append(matrix[r][c])
                mapbook[r][c] = 0
                #print("下")
            #左
            while(c > 0 and mapbook[r][c-1] == 1):
                c = c - 1
                res.append(matrix[r][c])
                mapbook[r][c] = 0
                #print("左")
            #上
            while(r > 0 and mapbook[r -1 ][c] == 1):
                r = r -1 
                res.append(matrix[r][c])
                mapbook[r][c] = 0
                #print("上")
        return res
发表于 2022-01-23 02:38:57 回复(0)
class Solution:
    def spiralOrder(self , matrix ):
        # write code here
        result = [] #返回值
        if matrix == []:
            return []
        # 当二维数组是空或任何一个维度是0,直接返回
        m = len(matrix) #行数
        n = len(matrix[0]) # 列数
        if m == 0 or n == 0:
            return result 
        # 二维数组的层数,取决于行和列的较小值
        sizes = (min(m,n)+1)//2
        #大循环,从外向内逐层遍历矩阵
        for i in range(sizes):
            # 从左到右遍历“上边”
            for j in range(i,n-i):
                result.append(matrix[i][j])
            # 从上到下遍历“右边”
            for j in range(i+1,m-i):
                result.append(matrix[j][(n-1)-i])
            # 从右到左遍历“下边”
            for j in range(i+1,n-i):
                #限制条件,因为当遍历内循环时候,四个内循环并不会全部执行
                if (m-1)-i > i: 
                    result.append(matrix[m-1-i][n-1-j])
            # 从下到上遍历“左边”
            for j in range(i+1,m-1-i):
                if i < (n-1)-i:
                    result.append(matrix[m-1-j][i])
        return result
发表于 2021-10-27 16:56:25 回复(0)
呼~
def spiralOrder(self , matrix ):
        i=len(matrix)
        list2=[]
        while i>=1:
            list2.extend(matrix[0])
            j=1
            while j<=i-1:
                a=[]
                k=0
                l=len(matrix[j])
                while k<=l-1:
                    a.append(matrix[j][l-1-k])
                    k+=1
                matrix[j]=a
                j+=1
            matrix=list(zip(*matrix[1:]))
            for i in range(len(matrix)):
                matrix[i]=list(matrix[i])
            i=len(matrix)
        return list2
发表于 2021-09-02 16:36:07 回复(0)
#
# 
# @param matrix int整型二维数组 
# @return int整型一维数组
# https://blog.csdn.net/thmx43/article/details/116738360?ops_request_misc=&request_id=&biz_id=102&utm_term=pythonnc38%20%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-.first_rank_v2_pc_rank_v29&spm=1018.2226.3001.4187

class Solution:
    def spiralOrder(self , matrix ):
        # write code here
        result = []
        if matrix == [] : return result
        m = len(matrix) 
        n = len(matrix[0]) 
        up = 0 
        down = m -1 
        left = 0 
        right = n - 1 
        x,y = 0,0
        ff = 1 
        if n == 1 : ff = 2
        for i in range(m*n) :
            tmp = matrix[x][y]
            result.append(tmp)
            if ff == 1 :
                y += 1 
                if y == right :
                    up += 1 
                    ff = 2 
                    continue
            elif ff == 2 :
                x += 1 
                if x == down :
                    right -= 1 
                    ff = 3 
                    continue
            elif ff == 3 :
                y -= 1 
                if y == left :
                    down -= 1
                    ff = 4
                    continue
            elif ff == 4 :
                x -= 1 
                if x == up :
                    left += 1 
                    ff = 1
                    continue
        return result

发表于 2021-08-24 11:18:58 回复(0)
class Solution:
    def spiralOrder(self , matrix ):
        m = len(matrix)        #行x
        if m ==0:
            return []
        n = len(matrix[0])    #列y
        ln = m*n                #总数
        x,y = 0,0
        res = []
        res = self.digui(matrix, m-1, n-1, res, x, y, ln)
        
        return res
    
    def digui(self , matrix, b_x, b_y, res, x, y, ln):
        #退出条件
        if ln == 0:
            return res
        
        res.append(matrix[x][y])
        
        
        
        direction = 1    # 增长方向代号,1:向右增长,2:向下增长,3:向左增长,4:向上增长
        
        br = n-1    # 右边界
        bd = m-1    # 下边界
        bl = 0    # 左边界
        bu = 1    # 上边界
        
        for i in range(ln):
            temp = matrix[x][y]
            res.append(temp)
            if direction == 1:
                y = y + 1
                if y ==br:
                    br = br - 1
                    direction = direction + 1    # 达到右边界,方向代号+1(即转为向下)
            elif direction == 2:
                x = x + 1
                if x == bd:
                    bd = bd - 1
                    direction = direction + 1    # 达到下边界,方向代号+1(即转为向左)
            elif direction ==3:
                y = y - 1
                if y ==bl:
                    bl = bl + 1
                    direction = direction + 1    # 达到左边界,方向代号+1(即转为向上)
            else :
                x = x - 1
                if x == bu:
                    bu = bu + 1
                    direction = 1    # 达到上边界,方向代号置为1(即转为向右)
        return res
发表于 2021-08-10 22:04:13 回复(0)
class Solution:
    def spiralOrder(self , matrix ):
        # write code here
        res = []
        while len(matrix) > 0 and len(matrix[0])>0:
            res.extend(matrix[0][:])
            del matrix[0]
            
            if len(matrix)>0 and len(matrix[0])>0:
                for i in range(len(matrix)):
                    res.append(matrix[i].pop())
            else:
                break
            if len(matrix)>0 and len(matrix[0])>0:
                res.extend(matrix[-1][::-1])
                del matrix[-1]
            else:
                break
            if len(matrix)>0 and len(matrix[0])>0:
                for k in range(len(matrix)-1, -1, -1):
                    res.append(matrix[k].pop(0))
            else:
                break
        return res
发表于 2021-08-10 21:49:50 回复(0)
# 方法很蠢,但是结构上还是比较清晰的

class Solution:
    def spiralOrder(self , matrix ):
        # write code here
        if not matrix:
            return []
        left = 0
        right = len(matrix[0])
        up = 0 
        down = len(matrix)
        res = []
        direction = 0
        while left < right and up < down:
            direction %= 4
            if direction == 0:
                for i in range(left,right):
                    res.append(matrix[up][i])
                up += 1
                direction += 1
            elif direction == 1:
                for j in range(up,down):
                    res.append(matrix[j][right-1])
                right -= 1
                direction += 1
            elif direction == 2:
                for i in range(right-1,left-1,-1):
                    res.append(matrix[down-1][i])
                down -= 1
                direction += 1
            elif direction == 3:
                for j in range(down-1, up-1, -1):
                    res.append(matrix[j][left])
                left += 1
                direction += 1
        return res

发表于 2021-07-26 13:45:30 回复(0)
#解法一:方向模拟
# 
# @param matrix int整型二维数组 
# @return int整型一维数组
#
class Solution:
    def spiralOrder(self , matrix ):
        # write code here
        '''
        想实现螺旋遍历,有两种思路:
        1. 按方向进行模拟:定义四个方向,一旦发生越界或下一个即将访问的位置已被访问过则转向
        2.按形状进行模拟:一圈一圈的进行遍历,先遍历外圈再遍历内圈。
        '''
        if len(matrix)==0:return []
        opt = [
            [0,1],
            [1,0],
            [0,-1],
            [-1,0]
        ]
        x,y,p = 0,0,0
        m,n = len(matrix),len(matrix[0])
        ans = []
        for i in range(m*n):
            ans.append(matrix[x][y])
            matrix[x][y] = '#'
            
            nx,ny = x+opt[p][0],y+opt[p][1]
            if nx < 0&nbs***bsp;nx >= m&nbs***bsp;ny <0&nbs***bsp;ny >= n&nbs***bsp;matrix[nx][ny] == '#':
                p = (p+1)%len(opt)
                nx,ny = x+opt[p][0],y+opt[p][1]
            x,y = nx,ny 
        return ans


#解法二:形状模拟
# 
# @param matrix int整型二维数组 
# @return int整型一维数组
#
class Solution:
    def spiralOrder(self , matrix ):
        # write code here
        '''
        想实现螺旋遍历,有两种思路:
        1. 按方向进行模拟:定义四个方向,一旦发生越界或下一个即将访问的位置已被访问过则转向
        2.按形状进行模拟:一圈一圈的进行遍历,先遍历外圈再遍历内圈。
        '''
        ans = []
        def circle(x1,x2,y1,y2):
            if x2 < x1 or y2 < y1:return
            
            if x1 == x2:
                for i in range(y1,y2+1):ans.append(matrix[x1][i])
                return
            if y1 == y2:
                for i in range(x1,x2+1):ans.append(matrix[i][y2])
                return
            
            for i in range(y1,y2):ans.append(matrix[x1][i])
            for i in range(x1,x2):ans.append(matrix[i][y2])
            for i in range(y2,y1,-1):ans.append(matrix[x2][i])
            for i in range(x2,x1,-1):ans.append(matrix[i][y1])
            
            circle(x1+1, x2-1, y1+1, y2-1)
        if len(matrix)==0:return []
        circle(0, len(matrix)-1, 0,len(matrix[0])-1)
        return ans
                
             

发表于 2021-07-19 20:17:38 回复(0)

问题信息

难度:
17条回答 24303浏览

热门推荐

通过挑战的用户